package ec;

import java.util.ArrayList;
import java.util.List;

public class IntegerSolution extends Solution {
	public boolean UNIFORM_CROSSOVER = true;

	private int[] _ints;

	private int _min;

	private int _max;

	private double _mutation_rate;

	private int _range;

	public IntegerSolution(int min, int max, int number_of_integers, double mutation_rate) {
		_min = min;
		_max = max;
		_mutation_rate = mutation_rate;
		
		// create a random list of integers within the given range
		_ints = new int[number_of_integers];
		_range = (max - min);
		for (int i = 0; i < number_of_integers; i++) {
			_ints[i] = randomInt();
		}
	}

	public IntegerSolution(int min, int max, int[] integers, double mutation_rate) {
		_mutation_rate = mutation_rate;
		_min = min;
		_max = max;
		_ints = integers;
	}
	
	protected int randomInt() {
		return (int) (Math.random() * _range) + _min;
	}

	@Override
	public List<Solution> crossover(Solution solutionB) {
		List<Solution> children = new ArrayList<Solution>(2);

		int[] intsB = ((IntegerSolution) solutionB)._ints;

		int lenA = _ints.length;
		int lenB = intsB.length;

		int indexA = (int) (Math.random() * _ints.length);
		int indexB = indexA;

		if (!UNIFORM_CROSSOVER) {
			indexB = (int) (Math.random() * _ints.length);
		}

		int childA_len = indexA + (lenB - indexB);
		int childB_len = indexB + (lenA - indexA);

		int[] childA = new int[childA_len];
		int[] childB = new int[childB_len];

		//
		// Create childA
		int child_idx = 0;

		// copy from parent A
		for (int i = 0; i < indexA; i++, child_idx++) {
			childA[child_idx] = _ints[i];
		}

		// copy from parent B
		for (int j = indexB; j < intsB.length; j++, child_idx++) {
			childA[child_idx] = intsB[j];
		}
		children.add(new IntegerSolution(_min, _max, childA, _mutation_rate));

		//
		// Create childB
		child_idx = 0;

		// copy from parent B
		for (int i = 0; i < indexB; i++, child_idx++) {
			childB[child_idx] = intsB[i];
		}

		// copy from parent A
		for (int j = indexA; j < _ints.length; j++, child_idx++) {
			childB[child_idx] = _ints[j];
		}
		children.add(new IntegerSolution(_min, _max, childB, _mutation_rate));

		return children;
	}

	@Override
	public Solution duplicate() {
		int[] ints = new int[_ints.length];
		System.arraycopy(_ints, 0, ints, 0, ints.length);
		return new IntegerSolution(_min, _max, ints, _mutation_rate);
	}

	@Override
	public String getSolutionString() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Solution mutate() {
		int[] ints = new int[_ints.length];
		
		for ( int i = 0; i < ints.length;i++) {
			if ( Math.random() < _mutation_rate) {
				ints[i] = randomInt();
			}
			else {
				ints[i] = _ints[i];
			}
		}
		
		return new IntegerSolution(_min, _max, ints, _mutation_rate);
	}

	public int[] getInts() {
		return _ints;
	}

}
